"""Knowledge Base and Solution Recommendation System.

Provides intelligent solution recommendations based on detected problems
and analysis results using a comprehensive knowledge base.
"""

import asyncio
import json
import logging
import time
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Any, Callable
from dataclasses import dataclass, field
from enum import Enum

from .diagnostic_engine import DetectedProblem, AnalysisResult, SolutionRecommendation, ProblemType, SeverityLevel

logger = logging.getLogger(__name__)


class SolutionType(Enum):
    """Solution type classification."""
    AUTOMATED_FIX = "automated_fix"
    MANUAL_PROCEDURE = "manual_procedure"
    CONFIGURATION_CHANGE = "configuration_change"
    SERVICE_RESTART = "service_restart"
    SYSTEM_MAINTENANCE = "system_maintenance"
    TROUBLESHOOTING_GUIDE = "troubleshooting_guide"
    EXTERNAL_ESCALATION = "external_escalation"


class DifficultyLevel(Enum):
    """Solution difficulty level."""
    EASY = "easy"      # Can be performed by anyone
    MEDIUM = "medium"  # Requires basic technical knowledge
    HARD = "hard"      # Requires advanced technical skills
    EXPERT = "expert"  # Requires expert knowledge


class RiskLevel(Enum):
    """Solution risk level."""
    LOW = "low"        # No risk of data loss or service disruption
    MEDIUM = "medium"  # Minor risk of temporary disruption
    HIGH = "high"      # Risk of significant disruption
    CRITICAL = "critical"  # Risk of data loss or system damage


@dataclass
class SolutionTemplate:
    """Template for solution generation."""
    solution_id: str
    name: str
    description: str
    solution_type: SolutionType
    applicable_problems: List[ProblemType]
    
    # Solution characteristics
    base_confidence: float
    historical_success_rate: float
    estimated_time: int  # seconds
    difficulty: DifficultyLevel
    risk_level: RiskLevel
    
    # Execution information
    is_automated: bool
    requires_approval: bool
    rollback_available: bool
    backup_required: bool
    
    # Steps and commands
    manual_steps: List[str] = field(default_factory=list)
    auto_fix_commands: List[Dict[str, Any]] = field(default_factory=list)
    verification_steps: List[str] = field(default_factory=list)
    
    # Conditions and prerequisites
    prerequisites: List[str] = field(default_factory=list)
    exclusion_conditions: List[str] = field(default_factory=list)
    component_filters: List[str] = field(default_factory=list)
    
    # Related resources
    kb_articles: List[str] = field(default_factory=list)
    external_links: List[str] = field(default_factory=list)
    tags: List[str] = field(default_factory=list)


@dataclass
class SolutionHistory:
    """Historical record of solution application."""
    solution_id: str
    problem_id: str
    device_id: str
    applied_at: datetime
    success: bool
    execution_time: int
    user_rating: Optional[int] = None  # 1-5 stars
    feedback: Optional[str] = None
    error_message: Optional[str] = None


class KnowledgeBase:
    """Knowledge base and solution recommendation engine."""
    
    def __init__(self, config: Dict[str, Any]):
        """Initialize knowledge base.
        
        Args:
            config: Knowledge base configuration
        """
        self.config = config.get("knowledge_base", {})
        
        # Knowledge base settings
        self.auto_update = self.config.get("auto_update", True)
        self.update_interval = self.config.get("update_interval", 86400)
        self.custom_solutions = self.config.get("custom_solutions", True)
        self.solution_rating = self.config.get("solution_rating", True)
        self.confidence_threshold = self.config.get("confidence_threshold", 0.5)
        self.max_recommendations = self.config.get("max_recommendations", 10)
        
        # Solution templates
        self.solution_templates: Dict[str, SolutionTemplate] = {}
        self.custom_templates: Dict[str, SolutionTemplate] = {}
        
        # Historical data
        self.solution_history: List[SolutionHistory] = []
        self.solution_ratings: Dict[str, float] = {}  # solution_id -> average rating
        self.solution_success_rates: Dict[str, float] = {}  # solution_id -> success rate
        
        # Pattern matching rules
        self.pattern_solutions: Dict[str, List[str]] = {}  # pattern -> solution IDs
        
        # Statistics
        self.statistics = {
            "recommendations_generated": 0,
            "solutions_applied": 0,
            "successful_solutions": 0,
            "failed_solutions": 0,
            "average_rating": 0.0,
            "knowledge_base_size": 0
        }
        
        # Load default knowledge base
        self._load_default_solutions()
        
        logger.info(f"KnowledgeBase initialized with {len(self.solution_templates)} solutions")
    
    def _load_default_solutions(self):
        """Load default solution templates."""
        
        # Network connectivity solutions
        self.solution_templates["restart_network_service"] = SolutionTemplate(
            solution_id="restart_network_service",
            name="Restart Network Service",
            description="Restart network-related services to restore connectivity",
            solution_type=SolutionType.SERVICE_RESTART,
            applicable_problems=[ProblemType.NETWORK_CONNECTIVITY, ProblemType.SERVICE_UNAVAILABLE],
            base_confidence=0.8,
            historical_success_rate=0.85,
            estimated_time=60,
            difficulty=DifficultyLevel.EASY,
            risk_level=RiskLevel.LOW,
            is_automated=True,
            requires_approval=False,
            rollback_available=True,
            backup_required=False,
            auto_fix_commands=[
                {"action": "systemctl", "params": ["restart", "networking"]},
                {"action": "wait", "params": [10]},
                {"action": "systemctl", "params": ["restart", "NetworkManager"]},
                {"action": "wait", "params": [5]},
                {"action": "test_connectivity", "params": ["google.com", "8.8.8.8"]}
            ],
            verification_steps=[
                "Check network interface status",
                "Test DNS resolution",
                "Verify internet connectivity"
            ],
            component_filters=["network_interface", "dns"],
            tags=["network", "connectivity", "service_restart"]
        )
        
        self.solution_templates["reset_network_configuration"] = SolutionTemplate(
            solution_id="reset_network_configuration",
            name="Reset Network Configuration",
            description="Reset network configuration to default settings",
            solution_type=SolutionType.CONFIGURATION_CHANGE,
            applicable_problems=[ProblemType.NETWORK_CONNECTIVITY, ProblemType.CONFIGURATION_ISSUE],
            base_confidence=0.7,
            historical_success_rate=0.75,
            estimated_time=300,
            difficulty=DifficultyLevel.MEDIUM,
            risk_level=RiskLevel.MEDIUM,
            is_automated=False,
            requires_approval=True,
            rollback_available=True,
            backup_required=True,
            manual_steps=[
                "Backup current network configuration",
                "Reset network interfaces to DHCP",
                "Clear DNS cache and reset DNS settings",
                "Restart network services",
                "Test connectivity to known servers",
                "Verify all network functions work correctly"
            ],
            prerequisites=["Admin privileges", "Network configuration backup"],
            exclusion_conditions=["Static IP required", "VPN active"],
            component_filters=["network_configuration"],
            tags=["network", "configuration", "reset"]
        )
        
        # Hardware resource solutions
        self.solution_templates["clear_system_cache"] = SolutionTemplate(
            solution_id="clear_system_cache",
            name="Clear System Cache",
            description="Clear system caches to free memory and improve performance",
            solution_type=SolutionType.SYSTEM_MAINTENANCE,
            applicable_problems=[ProblemType.RESOURCE_EXHAUSTION, ProblemType.PERFORMANCE_DEGRADATION],
            base_confidence=0.7,
            historical_success_rate=0.8,
            estimated_time=120,
            difficulty=DifficultyLevel.EASY,
            risk_level=RiskLevel.LOW,
            is_automated=True,
            requires_approval=False,
            rollback_available=False,
            backup_required=False,
            auto_fix_commands=[
                {"action": "sync", "params": []},
                {"action": "drop_caches", "params": [3]},
                {"action": "systemctl", "params": ["restart", "systemd-tmpfiles-clean"]},
                {"action": "wait", "params": [5]}
            ],
            verification_steps=[
                "Check available memory",
                "Verify system performance metrics",
                "Monitor resource usage trends"
            ],
            component_filters=["memory", "cache", "system_performance"],
            tags=["performance", "memory", "cache", "maintenance"]
        )
        
        self.solution_templates["kill_resource_hogs"] = SolutionTemplate(
            solution_id="kill_resource_hogs",
            name="Terminate Resource-Heavy Processes",
            description="Identify and terminate processes consuming excessive resources",
            solution_type=SolutionType.AUTOMATED_FIX,
            applicable_problems=[ProblemType.RESOURCE_EXHAUSTION, ProblemType.PERFORMANCE_DEGRADATION],
            base_confidence=0.6,
            historical_success_rate=0.7,
            estimated_time=30,
            difficulty=DifficultyLevel.MEDIUM,
            risk_level=RiskLevel.MEDIUM,
            is_automated=True,
            requires_approval=True,
            rollback_available=False,
            backup_required=False,
            auto_fix_commands=[
                {"action": "identify_resource_hogs", "params": ["cpu", 90]},
                {"action": "identify_resource_hogs", "params": ["memory", 85]},
                {"action": "terminate_processes", "params": ["non_critical_only"]},
                {"action": "wait", "params": [10]},
                {"action": "verify_resource_usage", "params": []}
            ],
            manual_steps=[
                "Review process list for resource-heavy applications",
                "Identify non-critical processes safe to terminate",
                "Gracefully stop applications if possible",
                "Force terminate unresponsive processes if needed",
                "Monitor system performance after cleanup"
            ],
            prerequisites=["Process management privileges"],
            exclusion_conditions=["Critical system processes only"],
            component_filters=["cpu", "memory", "processes"],
            tags=["performance", "processes", "resource_management"]
        )
        
        # Software error solutions
        self.solution_templates["restart_failed_services"] = SolutionTemplate(
            solution_id="restart_failed_services",
            name="Restart Failed Services",
            description="Restart services that have stopped or are in failed state",
            solution_type=SolutionType.SERVICE_RESTART,
            applicable_problems=[ProblemType.SOFTWARE_ERROR, ProblemType.SERVICE_UNAVAILABLE],
            base_confidence=0.8,
            historical_success_rate=0.85,
            estimated_time=90,
            difficulty=DifficultyLevel.EASY,
            risk_level=RiskLevel.LOW,
            is_automated=True,
            requires_approval=False,
            rollback_available=True,
            backup_required=False,
            auto_fix_commands=[
                {"action": "identify_failed_services", "params": []},
                {"action": "systemctl", "params": ["restart", "failed_services"]},
                {"action": "wait", "params": [15]},
                {"action": "verify_service_status", "params": []},
                {"action": "test_service_functionality", "params": []}
            ],
            verification_steps=[
                "Check service status using systemctl",
                "Verify service logs for errors",
                "Test service functionality"
            ],
            component_filters=["services", "systemd"],
            tags=["services", "restart", "software_error"]
        )
        
        # Configuration issue solutions
        self.solution_templates["validate_and_fix_config"] = SolutionTemplate(
            solution_id="validate_and_fix_config",
            name="Validate and Fix Configuration",
            description="Check configuration files for syntax errors and fix common issues",
            solution_type=SolutionType.CONFIGURATION_CHANGE,
            applicable_problems=[ProblemType.CONFIGURATION_ISSUE, ProblemType.SOFTWARE_ERROR],
            base_confidence=0.75,
            historical_success_rate=0.8,
            estimated_time=240,
            difficulty=DifficultyLevel.MEDIUM,
            risk_level=RiskLevel.MEDIUM,
            is_automated=False,
            requires_approval=True,
            rollback_available=True,
            backup_required=True,
            manual_steps=[
                "Backup current configuration files",
                "Run configuration syntax validation",
                "Fix identified syntax errors",
                "Check for missing required parameters",
                "Validate configuration against schema",
                "Test configuration with dry-run if available",
                "Apply configuration and restart services",
                "Verify system functionality"
            ],
            prerequisites=["Configuration file access", "Syntax validation tools"],
            component_filters=["configuration", "config_files"],
            tags=["configuration", "validation", "syntax_check"]
        )
        
        self.solution_templates["reset_to_default_config"] = SolutionTemplate(
            solution_id="reset_to_default_config",
            name="Reset to Default Configuration",
            description="Reset configuration files to their default state",
            solution_type=SolutionType.CONFIGURATION_CHANGE,
            applicable_problems=[ProblemType.CONFIGURATION_ISSUE],
            base_confidence=0.9,
            historical_success_rate=0.95,
            estimated_time=180,
            difficulty=DifficultyLevel.MEDIUM,
            risk_level=RiskLevel.HIGH,
            is_automated=False,
            requires_approval=True,
            rollback_available=True,
            backup_required=True,
            manual_steps=[
                "Create complete backup of current configuration",
                "Identify configuration files to reset",
                "Obtain default configuration templates",
                "Replace current configuration with defaults",
                "Customize essential settings (network, security)",
                "Restart affected services",
                "Test all system functionality",
                "Document changes made"
            ],
            prerequisites=["Admin access", "Default configuration templates"],
            exclusion_conditions=["Custom configurations critical for operation"],
            component_filters=["configuration"],
            tags=["configuration", "reset", "defaults"]
        )
        
        # Generic troubleshooting
        self.solution_templates["system_health_check"] = SolutionTemplate(
            solution_id="system_health_check",
            name="Comprehensive System Health Check",
            description="Perform comprehensive system diagnostics and health check",
            solution_type=SolutionType.TROUBLESHOOTING_GUIDE,
            applicable_problems=[ProblemType.HARDWARE_FAILURE, ProblemType.SOFTWARE_ERROR, 
                               ProblemType.PERFORMANCE_DEGRADATION],
            base_confidence=0.6,
            historical_success_rate=0.7,
            estimated_time=600,
            difficulty=DifficultyLevel.MEDIUM,
            risk_level=RiskLevel.LOW,
            is_automated=False,
            requires_approval=False,
            rollback_available=False,
            backup_required=False,
            manual_steps=[
                "Check system resource usage (CPU, memory, disk)",
                "Review system logs for errors and warnings",
                "Test hardware components (memory, disk, CPU)",
                "Verify network connectivity and performance",
                "Check service status and dependencies",
                "Validate system configuration integrity",
                "Run built-in diagnostic tools",
                "Generate comprehensive system report"
            ],
            component_filters=["system_health"],
            tags=["diagnostics", "health_check", "troubleshooting", "comprehensive"]
        )
        
        # Pattern-based solution mapping
        self.pattern_solutions = {
            "network_cascade": ["restart_network_service", "reset_network_configuration"],
            "resource_spiral": ["clear_system_cache", "kill_resource_hogs"],
            "config_conflict": ["validate_and_fix_config", "reset_to_default_config"],
            "hardware_cascade": ["system_health_check"],
            "service_failure": ["restart_failed_services", "system_health_check"]
        }
        
        # Update statistics
        self.statistics["knowledge_base_size"] = len(self.solution_templates)
    
    async def get_recommendations(self, problems: List[DetectedProblem], 
                                analysis_results: List[AnalysisResult]) -> List[SolutionRecommendation]:
        """Get solution recommendations for detected problems and analysis results.
        
        Args:
            problems: List of detected problems
            analysis_results: List of analysis results
            
        Returns:
            List of solution recommendations
        """
        if not problems:
            return []
        
        start_time = time.time()
        recommendations = []
        
        try:
            # Generate recommendations based on problems
            for problem in problems:
                problem_recommendations = await self._get_recommendations_for_problem(problem)
                recommendations.extend(problem_recommendations)
            
            # Generate recommendations based on analysis results
            for analysis in analysis_results:
                analysis_recommendations = await self._get_recommendations_for_analysis(analysis)
                recommendations.extend(analysis_recommendations)
            
            # Deduplicate and rank recommendations
            recommendations = self._deduplicate_recommendations(recommendations)
            recommendations = await self._rank_recommendations(recommendations, problems, analysis_results)
            
            # Filter by confidence threshold and limit count
            recommendations = [r for r in recommendations if r.confidence >= self.confidence_threshold]
            recommendations = recommendations[:self.max_recommendations]
            
            # Update statistics
            self.statistics["recommendations_generated"] += len(recommendations)
            
            processing_time = time.time() - start_time
            logger.info(f"Generated {len(recommendations)} recommendations in {processing_time:.2f}s")
            
        except Exception as e:
            logger.error(f"Error generating recommendations: {e}")
            recommendations = []
        
        return recommendations
    
    async def _get_recommendations_for_problem(self, problem: DetectedProblem) -> List[SolutionRecommendation]:
        """Get recommendations for a specific problem."""
        recommendations = []
        
        # Find applicable solution templates
        for solution_id, template in self.solution_templates.items():
            if self._is_solution_applicable(template, problem):
                recommendation = await self._create_recommendation_from_template(
                    template, problem, None
                )
                recommendations.append(recommendation)
        
        # Check custom solutions
        for solution_id, template in self.custom_templates.items():
            if self._is_solution_applicable(template, problem):
                recommendation = await self._create_recommendation_from_template(
                    template, problem, None
                )
                recommendations.append(recommendation)
        
        return recommendations
    
    async def _get_recommendations_for_analysis(self, analysis: AnalysisResult) -> List[SolutionRecommendation]:
        """Get recommendations for analysis results (patterns, correlations)."""
        recommendations = []
        
        # Check for pattern-based solutions
        for pattern_name in analysis.pattern_matches:
            if pattern_name in self.pattern_solutions:
                for solution_id in self.pattern_solutions[pattern_name]:
                    if solution_id in self.solution_templates:
                        template = self.solution_templates[solution_id]
                        recommendation = await self._create_recommendation_from_template(
                            template, None, analysis
                        )
                        recommendations.append(recommendation)
        
        # Correlation-based recommendations
        if "correlation" in analysis.analysis_type and analysis.correlation_score > 0.7:
            # High correlation suggests systemic issue - recommend comprehensive solutions
            if "system_health_check" in self.solution_templates:
                template = self.solution_templates["system_health_check"]
                recommendation = await self._create_recommendation_from_template(
                    template, None, analysis
                )
                # Boost confidence for systemic issues
                recommendation.confidence = min(1.0, recommendation.confidence + 0.1)
                recommendations.append(recommendation)
        
        return recommendations
    
    def _is_solution_applicable(self, template: SolutionTemplate, problem: DetectedProblem) -> bool:
        """Check if a solution template is applicable to a problem."""
        # Check problem type match
        if problem.problem_type not in template.applicable_problems:
            return False
        
        # Check component filters
        if template.component_filters:
            component_match = any(
                comp in problem.affected_components 
                for comp in template.component_filters
            )
            if not component_match:
                return False
        
        # Check exclusion conditions
        for exclusion in template.exclusion_conditions:
            if exclusion.lower() in problem.description.lower() or \
               exclusion.lower() in str(problem.symptom_data).lower():
                return False
        
        # Check severity vs risk level alignment
        if problem.severity == SeverityLevel.CRITICAL and template.risk_level == RiskLevel.LOW:
            # Critical problems may need higher-risk solutions
            pass
        elif problem.severity == SeverityLevel.LOW and template.risk_level == RiskLevel.CRITICAL:
            # Don't use high-risk solutions for low-severity problems
            return False
        
        return True
    
    async def _create_recommendation_from_template(self, template: SolutionTemplate,
                                                  problem: Optional[DetectedProblem],
                                                  analysis: Optional[AnalysisResult]) -> SolutionRecommendation:
        """Create a recommendation from a solution template."""
        # Generate unique recommendation ID
        recommendation_id = f"{template.solution_id}_{int(time.time())}"
        if problem:
            recommendation_id += f"_{problem.problem_id[:8]}"
        
        # Calculate confidence based on multiple factors
        confidence = template.base_confidence
        
        # Adjust confidence based on problem confidence
        if problem:
            confidence = (confidence + problem.confidence) / 2
        
        # Adjust confidence based on analysis results
        if analysis:
            confidence = (confidence + analysis.confidence) / 2
        
        # Apply historical success rate
        success_rate = self.solution_success_rates.get(template.solution_id, template.historical_success_rate)
        confidence = confidence * (0.7 + 0.3 * success_rate)
        
        # Apply user ratings if available
        user_rating = self.solution_ratings.get(template.solution_id, 3.0)  # Default 3/5
        confidence = confidence * (0.8 + 0.2 * (user_rating / 5.0))
        
        # Ensure confidence is within bounds
        confidence = max(0.1, min(1.0, confidence))
        
        # Create recommendation
        recommendation = SolutionRecommendation(
            recommendation_id=recommendation_id,
            solution_type=template.solution_type.value,
            title=template.name,
            description=template.description,
            confidence=confidence,
            success_rate=success_rate,
            estimated_time=template.estimated_time,
            difficulty=template.difficulty.value,
            is_automated=template.is_automated,
            requires_approval=template.requires_approval,
            manual_steps=template.manual_steps.copy(),
            auto_fix_commands=template.auto_fix_commands.copy(),
            risk_level=template.risk_level.value,
            rollback_available=template.rollback_available,
            backup_required=template.backup_required,
            related_kb_articles=template.kb_articles.copy(),
            external_links=template.external_links.copy()
        )
        
        return recommendation
    
    def _deduplicate_recommendations(self, recommendations: List[SolutionRecommendation]) -> List[SolutionRecommendation]:
        """Remove duplicate recommendations."""
        seen_solutions = set()
        unique_recommendations = []
        
        for recommendation in recommendations:
            # Create signature based on solution type and title
            signature = (recommendation.solution_type, recommendation.title)
            
            if signature not in seen_solutions:
                unique_recommendations.append(recommendation)
                seen_solutions.add(signature)
            else:
                # If duplicate, keep the one with higher confidence
                for i, existing in enumerate(unique_recommendations):
                    if (existing.solution_type, existing.title) == signature:
                        if recommendation.confidence > existing.confidence:
                            unique_recommendations[i] = recommendation
                        break
        
        return unique_recommendations
    
    async def _rank_recommendations(self, recommendations: List[SolutionRecommendation],
                                   problems: List[DetectedProblem],
                                   analysis_results: List[AnalysisResult]) -> List[SolutionRecommendation]:
        """Rank recommendations by relevance and effectiveness."""
        # Calculate ranking score for each recommendation
        for recommendation in recommendations:
            score = recommendation.confidence
            
            # Boost score for automated solutions (faster resolution)
            if recommendation.is_automated:
                score += 0.1
            
            # Boost score for low-risk solutions
            if recommendation.risk_level == RiskLevel.LOW.value:
                score += 0.05
            elif recommendation.risk_level == RiskLevel.HIGH.value:
                score -= 0.05
            
            # Boost score for solutions with rollback capability
            if recommendation.rollback_available:
                score += 0.05
            
            # Adjust score based on estimated time (prefer faster solutions)
            if recommendation.estimated_time < 120:  # Less than 2 minutes
                score += 0.1
            elif recommendation.estimated_time > 600:  # More than 10 minutes
                score -= 0.05
            
            # Adjust score based on success rate
            score += (recommendation.success_rate - 0.5) * 0.2
            
            # Apply problem severity weighting
            max_severity = max(p.severity.value for p in problems) if problems else 0
            if max_severity >= SeverityLevel.HIGH.value:
                # For high-severity problems, prefer more comprehensive solutions
                if "comprehensive" in recommendation.title.lower() or "system" in recommendation.title.lower():
                    score += 0.1
            
            # Store final ranking score
            recommendation._ranking_score = max(0.0, min(1.0, score))
        
        # Sort by ranking score (descending)
        return sorted(recommendations, key=lambda r: r._ranking_score, reverse=True)
    
    async def record_solution_feedback(self, solution_id: str, problem_id: str, 
                                     device_id: str, success: bool, 
                                     execution_time: int, user_rating: Optional[int] = None,
                                     feedback: Optional[str] = None,
                                     error_message: Optional[str] = None):
        """Record feedback about solution application."""
        # Create history record
        history = SolutionHistory(
            solution_id=solution_id,
            problem_id=problem_id,
            device_id=device_id,
            applied_at=datetime.now(),
            success=success,
            execution_time=execution_time,
            user_rating=user_rating,
            feedback=feedback,
            error_message=error_message
        )
        
        self.solution_history.append(history)
        
        # Update success rates
        solution_history = [h for h in self.solution_history if h.solution_id == solution_id]
        if solution_history:
            success_count = sum(1 for h in solution_history if h.success)
            self.solution_success_rates[solution_id] = success_count / len(solution_history)
        
        # Update user ratings
        if user_rating is not None:
            rated_history = [h for h in solution_history if h.user_rating is not None]
            if rated_history:
                total_rating = sum(h.user_rating for h in rated_history)
                self.solution_ratings[solution_id] = total_rating / len(rated_history)
        
        # Update statistics
        self.statistics["solutions_applied"] += 1
        if success:
            self.statistics["successful_solutions"] += 1
        else:
            self.statistics["failed_solutions"] += 1
        
        # Update average rating
        all_ratings = [h.user_rating for h in self.solution_history if h.user_rating is not None]
        if all_ratings:
            self.statistics["average_rating"] = sum(all_ratings) / len(all_ratings)
        
        logger.info(f"Recorded feedback for solution {solution_id}: success={success}, rating={user_rating}")
    
    def add_custom_solution(self, template: SolutionTemplate):
        """Add custom solution template."""
        self.custom_templates[template.solution_id] = template
        self.statistics["knowledge_base_size"] = len(self.solution_templates) + len(self.custom_templates)
        logger.info(f"Added custom solution: {template.name}")
    
    def remove_custom_solution(self, solution_id: str) -> bool:
        """Remove custom solution template."""
        if solution_id in self.custom_templates:
            del self.custom_templates[solution_id]
            self.statistics["knowledge_base_size"] = len(self.solution_templates) + len(self.custom_templates)
            logger.info(f"Removed custom solution: {solution_id}")
            return True
        return False
    
    def get_solution_statistics(self) -> Dict[str, Any]:
        """Get knowledge base statistics."""
        return {
            "knowledge_base_statistics": self.statistics.copy(),
            "solution_counts": {
                "default_solutions": len(self.solution_templates),
                "custom_solutions": len(self.custom_templates),
                "total_solutions": len(self.solution_templates) + len(self.custom_templates)
            },
            "solution_performance": {
                "average_success_rate": sum(self.solution_success_rates.values()) / len(self.solution_success_rates) if self.solution_success_rates else 0.0,
                "average_user_rating": self.statistics["average_rating"],
                "total_applications": len(self.solution_history)
            },
            "top_solutions": self._get_top_solutions(5)
        }
    
    def _get_top_solutions(self, count: int) -> List[Dict[str, Any]]:
        """Get top-performing solutions."""
        solution_performance = []
        
        for solution_id in set(list(self.solution_templates.keys()) + list(self.custom_templates.keys())):
            success_rate = self.solution_success_rates.get(solution_id, 0.0)
            user_rating = self.solution_ratings.get(solution_id, 0.0)
            applications = len([h for h in self.solution_history if h.solution_id == solution_id])
            
            # Calculate overall performance score
            score = (success_rate * 0.6) + (user_rating / 5.0 * 0.3) + (min(applications, 10) / 10.0 * 0.1)
            
            solution_performance.append({
                "solution_id": solution_id,
                "success_rate": success_rate,
                "user_rating": user_rating,
                "applications": applications,
                "performance_score": score
            })
        
        # Sort by performance score and return top solutions
        solution_performance.sort(key=lambda x: x["performance_score"], reverse=True)
        return solution_performance[:count]
    
    async def update_knowledge_base(self):
        """Update knowledge base with latest information."""
        if not self.auto_update:
            return
        
        try:
            # In a real implementation, this would:
            # 1. Download latest solution templates from remote repository
            # 2. Update success rates from aggregated data
            # 3. Add new community solutions
            # 4. Update pattern-solution mappings
            
            # For now, we'll just log the update
            logger.info("Knowledge base update completed (simulated)")
            
        except Exception as e:
            logger.error(f"Failed to update knowledge base: {e}")


# Example usage and testing
if __name__ == "__main__":
    import asyncio
    from .diagnostic_engine import DetectedProblem, ProblemType, SeverityLevel
    from datetime import datetime
    
    async def test_knowledge_base():
        """Test knowledge base functionality."""
        # Create configuration
        config = {
            "knowledge_base": {
                "auto_update": True,
                "confidence_threshold": 0.5,
                "max_recommendations": 5
            }
        }
        
        # Create knowledge base
        kb = KnowledgeBase(config)
        
        # Create test problems
        problems = [
            DetectedProblem(
                problem_id="test_net_001",
                problem_type=ProblemType.NETWORK_CONNECTIVITY,
                severity=SeverityLevel.HIGH,
                title="Network connectivity failure",
                description="Cannot reach external servers",
                detector_name="network_detector",
                detected_at=datetime.now(),
                confidence=0.9,
                symptom_data={"failed_connections": 5},
                affected_components=["network_interface", "dns"]
            ),
            DetectedProblem(
                problem_id="test_cpu_001",
                problem_type=ProblemType.RESOURCE_EXHAUSTION,
                severity=SeverityLevel.MEDIUM,
                title="High CPU usage",
                description="CPU usage at 95%",
                detector_name="hardware_detector",
                detected_at=datetime.now(),
                confidence=0.8,
                symptom_data={"cpu_percent": 95},
                affected_components=["cpu"]
            )
        ]
        
        print("Testing knowledge base...")
        
        # Get recommendations
        recommendations = await kb.get_recommendations(problems, [])
        
        print(f"Generated {len(recommendations)} recommendations:")
        for i, rec in enumerate(recommendations, 1):
            print(f"\n{i}. {rec.title}")
            print(f"   Type: {rec.solution_type}")
            print(f"   Confidence: {rec.confidence:.2f}")
            print(f"   Success Rate: {rec.success_rate:.2f}")
            print(f"   Estimated Time: {rec.estimated_time}s")
            print(f"   Automated: {rec.is_automated}")
            print(f"   Risk Level: {rec.risk_level}")
            if rec.manual_steps:
                print(f"   Manual Steps: {len(rec.manual_steps)}")
        
        # Test feedback recording
        if recommendations:
            await kb.record_solution_feedback(
                solution_id="restart_network_service",
                problem_id="test_net_001",
                device_id="test_device",
                success=True,
                execution_time=45,
                user_rating=4,
                feedback="Fixed the network issue quickly"
            )
        
        # Get statistics
        stats = kb.get_solution_statistics()
        print(f"\nKnowledge Base Statistics: {stats}")
    
    # Run test
    asyncio.run(test_knowledge_base())